package com.coursehub.exercise.controller;

import com.coursehub.exercise.dto.ExerciseCreateDto;
import com.coursehub.exercise.dto.ExerciseUpdateDto;
import com.coursehub.exercise.entity.Exercise;
import com.coursehub.exercise.entity.FavoriteQuestionBank;
import com.coursehub.exercise.entity.FavoriteQuestionBankQuestion;
import com.coursehub.exercise.entity.FavoriteQuestionBankQuestionId;
import com.coursehub.exercise.entity.WrongQuestionBank;
import com.coursehub.exercise.entity.Question;
import com.coursehub.exercise.repository.FavoriteQuestionBankRepository;
import com.coursehub.exercise.repository.FavoriteQuestionBankQuestionRepository;
import com.coursehub.exercise.repository.WrongQuestionBankRepository;
import com.coursehub.exercise.repository.WrongQuestionBankQuestionRepository;
import com.coursehub.exercise.repository.QuestionRepository;
import com.coursehub.exercise.service.FavoriteQuestionBankService;
import com.coursehub.exercise.service.ExerciseService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 练习管理控制器
 */
@Slf4j
@RestController
@RequestMapping("/api/exercises")
@RequiredArgsConstructor
public class ExerciseController {
    
    private final ExerciseService exerciseService;
    private final FavoriteQuestionBankRepository favoriteQuestionBankRepository;
    private final FavoriteQuestionBankQuestionRepository favoriteQuestionBankQuestionRepository;
    private final WrongQuestionBankRepository wrongQuestionBankRepository;
    private final WrongQuestionBankQuestionRepository wrongQuestionBankQuestionRepository;
    private final QuestionRepository questionRepository;
    private final FavoriteQuestionBankService favoriteQuestionBankService;
    
    /**
     * 创建练习
     */
    @PostMapping
    public ResponseEntity<Exercise> createExercise(@Valid @RequestBody ExerciseCreateDto createDto) {
        log.info("创建练习请求: {}", createDto.getExerciseName());
        Exercise exercise = exerciseService.createExercise(createDto);
        return ResponseEntity.status(HttpStatus.CREATED).body(exercise);
    }
    
    /**
     * 根据ID获取练习
     */
    @GetMapping("/{exerciseId}")
    public ResponseEntity<Exercise> getExerciseById(@PathVariable String exerciseId) {
        log.debug("获取练习详情: {}", exerciseId);
        return exerciseService.getExerciseById(exerciseId)
                .map(exercise -> ResponseEntity.ok(exercise))
                .orElse(ResponseEntity.notFound().build());
    }
    
    /**
     * 获取所有练习
     */
    @GetMapping
    public ResponseEntity<List<Exercise>> getAllExercises() {
        log.debug("获取所有练习");
        List<Exercise> exercises = exerciseService.getAllExercises();
        return ResponseEntity.ok(exercises);
    }
    
    /**
     * 分页获取练习
     */
    @GetMapping("/page")
    public ResponseEntity<Page<Exercise>> getExercises(Pageable pageable) {
        log.debug("分页获取练习");
        Page<Exercise> exercises = exerciseService.getExercises(pageable);
        return ResponseEntity.ok(exercises);
    }
    
    /**
     * 更新练习
     */
    @PutMapping("/{exerciseId}")
    public ResponseEntity<Exercise> updateExercise(
            @PathVariable String exerciseId,
            @Valid @RequestBody ExerciseUpdateDto updateDto) {
        log.info("更新练习请求: {}", exerciseId);
        Exercise exercise = exerciseService.updateExercise(exerciseId, updateDto);
        return ResponseEntity.ok(exercise);
    }
    
    /**
     * 删除练习
     */
    @DeleteMapping("/{exerciseId}")
    public ResponseEntity<Void> deleteExercise(@PathVariable String exerciseId) {
        log.info("删除练习请求: {}", exerciseId);
        exerciseService.deleteExercise(exerciseId);
        return ResponseEntity.noContent().build();
    }
    
    /**
     * 根据名称搜索练习
     */
    @GetMapping("/search")
    public ResponseEntity<List<Exercise>> searchExercisesByName(@RequestParam String name) {
        log.debug("搜索练习: {}", name);
        List<Exercise> exercises = exerciseService.searchExercisesByName(name);
        return ResponseEntity.ok(exercises);
    }
    
    /**
     * 根据班级ID获取练习
     */
    @GetMapping("/class/{classesId}")
    public ResponseEntity<List<Exercise>> getExercisesByClassId(@PathVariable String classesId) {
        log.debug("获取班级练习: {}", classesId);
        List<Exercise> exercises = exerciseService.getExercisesByClassId(classesId);
        return ResponseEntity.ok(exercises);
    }
    
    /**
     * 根据班级ID获取进行中的练习
     */
    @GetMapping("/class/{classesId}/active")
    public ResponseEntity<List<Exercise>> getActiveExercisesByClassId(@PathVariable String classesId) {
        log.debug("获取班级进行中的练习: {}", classesId);
        List<Exercise> exercises = exerciseService.getActiveExercisesByClassId(classesId);
        return ResponseEntity.ok(exercises);
    }
    
    /**
     * 根据班级ID获取已结束的练习
     */
    @GetMapping("/class/{classesId}/finished")
    public ResponseEntity<List<Exercise>> getFinishedExercisesByClassId(@PathVariable String classesId) {
        log.debug("获取班级已结束的练习: {}", classesId);
        List<Exercise> exercises = exerciseService.getFinishedExercisesByClassId(classesId);
        return ResponseEntity.ok(exercises);
    }
    
    /**
     * 根据班级ID获取未开始的练习
     */
    @GetMapping("/class/{classesId}/upcoming")
    public ResponseEntity<List<Exercise>> getUpcomingExercisesByClassId(@PathVariable String classesId) {
        log.debug("获取班级未开始的练习: {}", classesId);
        List<Exercise> exercises = exerciseService.getUpcomingExercisesByClassId(classesId);
        return ResponseEntity.ok(exercises);
    }
    
    /**
     * 检查练习是否存在（通过ID）
     */
    @GetMapping("/{exerciseId}/exists")
    public ResponseEntity<Boolean> checkExerciseExists(@PathVariable String exerciseId) {
        log.debug("检查练习是否存在: {}", exerciseId);
        boolean exists = exerciseService.existsById(exerciseId);
        return ResponseEntity.ok(exists);
    }
    
    /**
     * 检查练习是否存在（通过名称）
     */
    @GetMapping("/name/{exerciseName}/exists")
    public ResponseEntity<Boolean> checkExerciseNameExists(@PathVariable String exerciseName) {
        log.debug("检查练习名称是否存在: {}", exerciseName);
        boolean exists = exerciseService.existsByName(exerciseName);
        return ResponseEntity.ok(exists);
    }
    
    /**
     * 根据多个条件搜索练习
     */
    @GetMapping("/search/advanced")
    public ResponseEntity<List<Exercise>> searchExercises(
            @RequestParam(required = false) String exerciseName,
            @RequestParam(required = false) String classesId,
            @RequestParam(required = false) Boolean isMultipleSubmission) {
        log.debug("高级搜索练习");
        List<Exercise> exercises = exerciseService.searchExercises(exerciseName, classesId, isMultipleSubmission);
        return ResponseEntity.ok(exercises);
    }
    
    /**
     * 验证班级权限（仅验证班级是否存在）
     */
    @GetMapping("/validate/class/{classesId}")
    public ResponseEntity<Boolean> validateClassPermission(@PathVariable String classesId) {
        log.debug("验证班级权限: {}", classesId);
        boolean hasPermission = exerciseService.validateClassPermission(classesId);
        return ResponseEntity.ok(hasPermission);
    }
    
    /**
     * 验证用户对班级的权限
     */
    @GetMapping("/validate/class/{classesId}/user/{userId}")
    public ResponseEntity<Boolean> validateClassPermissionForUser(
            @PathVariable String classesId, 
            @PathVariable String userId) {
        log.debug("验证用户对班级的权限: classesId={}, userId={}", classesId, userId);
        boolean hasPermission = exerciseService.validateClassPermission(classesId, userId);
        return ResponseEntity.ok(hasPermission);
    }
    
    // ====================== 兼容单体系统的扩展API ======================
    
    /**
     * 获取课程下所有练习
     * 兼容单体系统API: GET /api/exercises/course/{courseId}
     */
    @GetMapping("/course/{courseId}")
    public ResponseEntity<List<Exercise>> getAllCourseExercises(@PathVariable String courseId) {
        log.debug("获取课程练习: {}", courseId);
        List<Exercise> exercises = exerciseService.getAllCourseExercises(courseId);
        return ResponseEntity.ok(exercises);
    }
    
    /**
     * 获取用户未完成的练习（按课程）
     * 兼容单体系统API: GET /api/exercises/unfinished
     */
    @GetMapping("/unfinished")
    public ResponseEntity<List<Exercise>> getUnfinishedExercises(
            @RequestParam String courseId,
            @RequestParam String userId) {
        log.debug("获取未完成练习: courseId={}, userId={}", courseId, userId);
        List<Exercise> exercises = exerciseService.getUnfinishedExercises(courseId, userId);
        return ResponseEntity.ok(exercises);
    }
    
    /**
     * 获取用户已完成的练习（按课程）
     * 兼容单体系统API: GET /api/exercises/finished
     */
    @GetMapping("/finished")
    public ResponseEntity<List<Exercise>> getFinishedExercises(
            @RequestParam String courseId,
            @RequestParam String userId) {
        log.debug("获取已完成练习: courseId={}, userId={}", courseId, userId);
        List<Exercise> exercises = exerciseService.getFinishedExercises(courseId, userId);
        return ResponseEntity.ok(exercises);
    }
    
    /**
     * 获取练习详情（包含用户状态）
     * 兼容单体系统API: GET /api/exercises/{exerciseId}/detail
     */
    @GetMapping("/{exerciseId}/detail")
    public ResponseEntity<Map<String, Object>> getExerciseDetail(
            @PathVariable String exerciseId,
            @RequestParam String userId) {
        log.debug("获取练习详情: exerciseId={}, userId={}", exerciseId, userId);
        Map<String, Object> detail = exerciseService.getExerciseDetail(exerciseId, userId);
        return ResponseEntity.ok(detail);
    }
    
    /**
     * 获取练习下的所有题目
     * 兼容单体系统API: GET /api/exercises/{exerciseId}/questions
     */
    @GetMapping("/{exerciseId}/questions")
    public ResponseEntity<List<Map<String, Object>>> getExerciseQuestions(@PathVariable String exerciseId) {
        log.debug("获取练习题目: {}", exerciseId);
        List<Map<String, Object>> questions = exerciseService.getExerciseQuestions(exerciseId);
        return ResponseEntity.ok(questions);
    }
    
    /**
     * 提交练习及答案
     * 兼容单体系统API: POST /api/exercises/submitted
     */
    @PostMapping("/submitted")
    public ResponseEntity<String> submitExercise(@RequestBody Map<String, Object> submissionRequest) {
        log.info("提交练习答案");
        exerciseService.submitExercise(submissionRequest);
        return ResponseEntity.ok("练习提交成功");
    }
    
    /**
     * 获取练习下的所有学生练习记录
     * 兼容单体系统API: GET /api/exercises/{exerciseId}/student-exercises
     */
    @GetMapping("/{exerciseId}/student-exercises")
    public ResponseEntity<List<Map<String, Object>>> getAllStudentExercise(@PathVariable String exerciseId) {
        log.debug("获取学生练习记录: {}", exerciseId);
        List<Map<String, Object>> studentExercises = exerciseService.getAllStudentExercise(exerciseId);
        return ResponseEntity.ok(studentExercises);
    }
    
    /**
     * 获取学生在某练习中的所有答案
     * 兼容单体系统API: GET /api/exercises/{exerciseId}/student-answers
     */
    @GetMapping("/{exerciseId}/student-answers")
    public ResponseEntity<List<Map<String, Object>>> getAllStudentQuestionAnswer(
            @PathVariable String exerciseId,
            @RequestParam String studentId) {
        log.debug("获取学生答案: exerciseId={}, studentId={}", exerciseId, studentId);
        List<Map<String, Object>> answers = exerciseService.getAllStudentQuestionAnswer(exerciseId, studentId);
        return ResponseEntity.ok(answers);
    }
    
    /**
     * 获取班级待批改的练习列表
     * 兼容单体系统API: GET /api/exercises/classes/{classesId}/grading
     */
    @GetMapping("/classes/{classesId}/grading")
    public ResponseEntity<List<Map<String, Object>>> getClassExercisesForGrading(@PathVariable String classesId) {
        log.debug("获取班级待批改练习: {}", classesId);
        List<Map<String, Object>> exercises = exerciseService.getClassExercisesForGrading(classesId);
        return ResponseEntity.ok(exercises);
    }
    
    /**
     * 获取学生练习详情（用于批改）
     * 兼容单体系统API: GET /api/exercises/{exerciseId}/grading/{studentId}
     */
    @GetMapping("/{exerciseId}/grading/{studentId}")
    public ResponseEntity<Map<String, Object>> getStudentExerciseForGrading(
            @PathVariable String exerciseId,
            @PathVariable String studentId) {
        log.debug("获取学生练习批改详情: exerciseId={}, studentId={}", exerciseId, studentId);
        @SuppressWarnings("unchecked")
        Map<String, Object> detail = (Map<String, Object>) exerciseService.getStudentExerciseForGrading(exerciseId, studentId);
        return ResponseEntity.ok(detail);
    }
    
    /**
     * 提交批改结果
     * 兼容单体系统API: POST /api/exercises/grading/submit
     */
    @PostMapping("/grading/submit")
    public ResponseEntity<String> submitGrades(@RequestBody Map<String, Object> gradeSubmission) {
        log.info("提交批改结果");
        exerciseService.submitGrades(gradeSubmission);
        return ResponseEntity.ok("批改结果提交成功");
    }
    
    /**
     * 级联删除练习（含题目、答案、收藏等）
     * 兼容单体系统API: POST /api/exercises/cascade/{exerciseId}
     */
    @PostMapping("/cascade/{exerciseId}")
    public ResponseEntity<String> cascadeDeleteExercise(@PathVariable String exerciseId) {
        log.info("级联删除练习: {}", exerciseId);
        exerciseService.cascadeDeleteExercise(exerciseId);
        return ResponseEntity.ok("练习删除成功");
    }
    
    /**
     * 加载课程题库题目
     * 兼容单体系统API: GET /api/exercises/bank/{courseId}/questions
     */
    @GetMapping("/bank/{courseId}/questions")
    public ResponseEntity<List<Map<String, Object>>> loadCourseQuestions(@PathVariable String courseId) {
        log.debug("加载课程题库: {}", courseId);
        List<Map<String, Object>> questions = exerciseService.loadCourseQuestions(courseId);
        return ResponseEntity.ok(questions);
    }
    
    /**
     * 添加题目到课程题库
     * 兼容单体系统API: POST /api/exercises/bank/{courseId}/questions
     */
    @PostMapping("/bank/{courseId}/questions")
    public ResponseEntity<Map<String, Object>> addQuestionToBank(
            @PathVariable String courseId,
            @RequestBody Map<String, Object> question) {
        log.info("添加题目到课程题库: {}", courseId);
        @SuppressWarnings("unchecked")
        Map<String, Object> savedQuestion = (Map<String, Object>) exerciseService.addQuestionToBank(courseId, question);
        return ResponseEntity.status(HttpStatus.CREATED).body(savedQuestion);
    }
    
    /**
     * 从课程题库删除题目
     * 兼容单体系统API: POST /api/exercises/bank/{courseId}/questions/{questionId}
     */
    @PostMapping("/bank/{courseId}/questions/{questionId}")
    public ResponseEntity<String> deleteQuestionFromBank(
            @PathVariable String courseId,
            @PathVariable String questionId) {
        log.info("从课程题库删除题目: courseId={}, questionId={}", courseId, questionId);
        exerciseService.deleteQuestionFromBank(courseId, questionId);
        return ResponseEntity.ok("题目删除成功");
    }
    
    /**
     * 添加题目到练习
     * 用于将已有题目关联到练习，而不是重新创建题目
     */
    @PostMapping("/{exerciseId}/questions/{questionId}")
    public ResponseEntity<String> addQuestionToExercise(
            @PathVariable String exerciseId,
            @PathVariable String questionId) {
        log.info("添加题目到练习: exerciseId={}, questionId={}", exerciseId, questionId);
        exerciseService.addQuestionToExercise(exerciseId, questionId);
        return ResponseEntity.ok("题目添加到练习成功");
    }

    /**
     * 计算学生排名（兼容单体：POST /api/exercises/{exerciseId}/ranking/{userId}）
     */
    @PostMapping("/{exerciseId}/ranking/{userId}")
    public ResponseEntity<Integer> calculateStudentRank(
            @PathVariable String exerciseId,
            @PathVariable String userId) {
        int rank = exerciseService.calculateStudentRank(exerciseId, userId);
        return ResponseEntity.ok(rank);
    }
    
    /**
     * 根据课程ID和用户ID获取班级ID
     * 兼容单体系统API: GET /api/exercises/classes-id
     */
    @GetMapping("/classes-id")
    public ResponseEntity<String> getClassesIdByCourseAndUser(
            @RequestParam String courseId,
            @RequestParam String userId) {
        log.debug("获取班级ID: courseId={}, userId={}", courseId, userId);
        String classId = exerciseService.getClassesIdByCourseAndUser(courseId, userId);
        return ResponseEntity.ok(classId);
    }
    
    /**
     * 根据课程ID和用户ID查询该用户作为教师的所有班级
     * 兼容单体系统API: GET /api/exercises/classes/teacher
     */
    @GetMapping("/classes/teacher")
    public ResponseEntity<List<Map<String, Object>>> getClassesAsTeacher(
            @RequestParam String courseId,
            @RequestParam String userId) {
        log.debug("获取教师班级: courseId={}, userId={}", courseId, userId);
        List<Map<String, Object>> classes = exerciseService.getClassesAsTeacher(courseId, userId);
        return ResponseEntity.ok(classes);
    }

    // ---------------------- 收藏与错题管理（兼容单体端点） ----------------------

    /**
     * 添加收藏题目（兼容单体：POST /api/exercises/favorite）
     */
    @PostMapping("/favorite")
    public ResponseEntity<Void> addFavoriteQuestion(
            @RequestParam String userId,
            @RequestParam String courseId,
            @RequestParam String questionId) {
        // 获取或创建收藏题库
        List<FavoriteQuestionBank> banks = favoriteQuestionBankRepository.findByUserIdAndCourseId(userId, courseId);
        FavoriteQuestionBank bank;
        if (banks == null || banks.isEmpty()) {
            String bankId = java.util.UUID.randomUUID().toString();
            bank = favoriteQuestionBankService.create(bankId, userId, courseId);
        } else {
            bank = banks.get(0);
        }

        // 关联题目
        if (!favoriteQuestionBankQuestionRepository.existsByIdFavoriteQuestionBankIdAndIdQuestionId(bank.getFavoriteQuestionBankId(), questionId)) {
            FavoriteQuestionBankQuestion relation = new FavoriteQuestionBankQuestion();
            relation.setId(new FavoriteQuestionBankQuestionId(bank.getFavoriteQuestionBankId(), questionId));
            favoriteQuestionBankQuestionRepository.save(relation);
        }
        return ResponseEntity.ok().build();
    }

    /**
     * 取消收藏题目（兼容单体：POST /api/exercises/unfavorite）
     */
    @PostMapping("/unfavorite")
    public ResponseEntity<Void> removeFavoriteQuestion(
            @RequestParam String userId,
            @RequestParam String courseId,
            @RequestParam String questionId) {
        List<FavoriteQuestionBank> banks = favoriteQuestionBankRepository.findByUserIdAndCourseId(userId, courseId);
        if (banks != null && !banks.isEmpty()) {
            String bankId = banks.get(0).getFavoriteQuestionBankId();
            favoriteQuestionBankQuestionRepository.deleteByIdFavoriteQuestionBankIdAndIdQuestionId(bankId, questionId);
        }
        return ResponseEntity.ok().build();
    }

    /**
     * 获取收藏题目列表（兼容单体：GET /api/exercises/favorite）
     */
    @GetMapping("/favorite")
    public ResponseEntity<List<Question>> getFavoriteQuestionBank(
            @RequestParam String userId,
            @RequestParam String courseId) {
        List<FavoriteQuestionBank> banks = favoriteQuestionBankRepository.findByUserIdAndCourseId(userId, courseId);
        if (banks == null || banks.isEmpty()) {
            return ResponseEntity.ok(java.util.List.of());
        }
        String bankId = banks.get(0).getFavoriteQuestionBankId();
        List<String> questionIds = favoriteQuestionBankQuestionRepository
                .findByIdFavoriteQuestionBankId(bankId)
                .stream()
                .map(r -> r.getId().getQuestionId())
                .toList();
        if (questionIds.isEmpty()) {
            return ResponseEntity.ok(java.util.List.of());
        }
        List<Question> questions = questionRepository.findByQuestionIdIn(questionIds);
        return ResponseEntity.ok(questions);
    }

    /**
     * 获取错题集（兼容单体：GET /api/exercises/wrong）
     */
    @GetMapping("/wrong")
    public ResponseEntity<List<Question>> getWrongQuestionBank(
            @RequestParam String userId,
            @RequestParam String courseId) {
        List<WrongQuestionBank> banks = wrongQuestionBankRepository.findByUserIdAndCourseId(userId, courseId);
        if (banks == null || banks.isEmpty()) {
            return ResponseEntity.ok(java.util.List.of());
        }
        String bankId = banks.get(0).getWrongQuestionBankId();
        List<String> questionIds = wrongQuestionBankQuestionRepository
                .findByIdWrongQuestionBankId(bankId)
                .stream()
                .map(r -> r.getId().getQuestionId())
                .toList();
        if (questionIds.isEmpty()) {
            return ResponseEntity.ok(java.util.List.of());
        }
        List<Question> questions = questionRepository.findByQuestionIdIn(questionIds);
        return ResponseEntity.ok(questions);
    }
    
    /**
     * 获取用户在课程中的角色
     * 兼容前端对 /api/exercises/role 接口的调用
     */
    @GetMapping("/role")
    public ResponseEntity<Map<String, String>> getUserRole(
            @RequestParam("courseId") String courseId, 
            @RequestParam("userId") String userId) {
        log.debug("获取用户角色: courseId={}, userId={}", courseId, userId);
        String role = exerciseService.getUserRole(courseId, userId);
        Map<String, String> response = new HashMap<>();
        response.put("role", role);
        return ResponseEntity.ok(response);
    }
}